#include "CD3D9Mapping.h"

BEGIN_WARE

////the combination of D3DUSAGE values for Ogre buffer eUsage
DWORD CD3D9Mapping::get( USAGE eUsage )
{
	DWORD ret = 0;

	if( eUsage & HBU_DYNAMIC )
	{
		ret |= D3DUSAGE_DYNAMIC;
	}
	else
	{
		ret = 0;

		if ( eUsage & HBU_WRITEONLY )
		{
			ret |= D3DUSAGE_WRITEONLY;
		}
	}

	return ret;
}
/////// Get lock eOptions
DWORD CD3D9Mapping::get( LOCKOPTIONS eOptions, USAGE eUsage )
{
	DWORD ret = 0;

	if( eOptions == HBL_DISCARDABLE )
	{
		//#if OGRE_D3D_MANAGE_BUFFERS
		// Only add the discard flag for dynamic usgae and default pool
		if ((eUsage & HBU_DYNAMIC) )// &&
		{	//(eUsage & CHardwareBuffer::HBU_DISCARDABLE))
			ret |= D3DLOCK_DISCARD;
		}
		//#else
		//			 D3D doesn't like discard or no_overwrite on non-dynamic buffers
		//			if (eUsage & CHardwareBuffer::HBU_DYNAMIC)
		//				ret |= D3DLOCK_DISCARD;
		//#endif
	}

	if (eOptions == HBL_READ_ONLY)
	{
		ret |= D3DLOCK_READONLY;
	}

	if( eOptions == HBL_NO_OVERWRITE )
	{
		//#if OGRE_D3D_MANAGE_BUFFERS
		// Only add the nooverwrite flag for dynamic usgae and default pool
		if ((eUsage & HBU_DYNAMIC) ) //&&
		{	//(eUsage & CHardwareBuffer::HBU_DISCARDABLE))
			ret |= D3DLOCK_NOOVERWRITE;
		}
		//#else
		//			// D3D doesn't like discard or no_overwrite on non-dynamic buffers
		//			if (eUsage & CHardwareBuffer::HBU_DYNAMIC)
		//				ret |= D3DLOCK_NOOVERWRITE;
		//#endif 
	}

	return ret;
}
//// Get index eType
D3DFORMAT CD3D9Mapping::get( IndexType eIndexType )
{
	if( eIndexType == IT_INDEX32 )
	{
		return D3DFMT_INDEX32;
	}
	else
	{
		return D3DFMT_INDEX16;
	}
}
//
// Get vertex data eType
D3DDECLTYPE CD3D9Mapping::get( VertexElementType eType )
{
	switch(eType)
	{
	case VET_COLOR:
		return D3DDECLTYPE_D3DCOLOR;
		break;
	case VET_FLOAT1:
		return D3DDECLTYPE_FLOAT1;
		break;
	case VET_FLOAT2:
		return D3DDECLTYPE_FLOAT2;
		break;
	case VET_FLOAT3:
		return D3DDECLTYPE_FLOAT3;
		break;
	case VET_FLOAT4:
		return D3DDECLTYPE_FLOAT4;
		break;
	case VET_SHORT2:
		return D3DDECLTYPE_SHORT2;
		break;
	case VET_SHORT4:
		return D3DDECLTYPE_SHORT4;
		break;
	case VET_UBYTE4:
		return D3DDECLTYPE_UBYTE4;
		break;
	default:
		return D3DDECLTYPE_FLOAT3;
		break;

	}

}
/// Get vertex eSemantic
D3DDECLUSAGE CD3D9Mapping::get( VertexElementSemantic eSem )
{
	switch(eSem)
	{
	case VES_BLEND_INDICES:
		return D3DDECLUSAGE_BLENDINDICES;
		//break;
	case VES_BLEND_WEIGHTS:
		return D3DDECLUSAGE_BLENDWEIGHT;
		//break;
	case VES_DIFFUSE:
		return D3DDECLUSAGE_COLOR; // NB index will differentiate
		//break;
	case VES_SPECULAR:
		return D3DDECLUSAGE_COLOR; // NB index will differentiate
		//break;
	case VES_NORMAL:
		return D3DDECLUSAGE_NORMAL;
		//break;
	case VES_POSITION:
		return D3DDECLUSAGE_POSITION;
		//break;
	case VES_TEXTURE_COORDINATES:
		return D3DDECLUSAGE_TEXCOORD;
		//break;
	case VES_BINORMAL:
		return D3DDECLUSAGE_BINORMAL;
		//break;
	case VES_TANGENT:
		return D3DDECLUSAGE_TANGENT;
		//break;
	default:
		return D3DDECLUSAGE_POSITION;
		//break;
	}
}

D3DFORMAT CD3D9Mapping::get( PixelFormat eFormat )
{
	switch( eFormat )
	{
		/// 16-bit pixel format, 5 bits red, 6 bits green, 5 bits blue.
	case PF_R5G6B5:
		{
			return D3DFMT_R5G6B5;
		}
		/// 16-bit pixel format, 5 bits for blue, green, red and 1 for alpha.
	case PF_A1R5G5B5:
		{
			return D3DFMT_A1R5G5B5;
		}

		/// 24-bit pixel format, 8 bits for red, green and blue.
	case PF_R8G8B8:
		{
			return D3DFMT_R8G8B8;
		}
		/// 24-bit pixel format, 8 bits for blue, green and red.
	case PF_A8R8G8B8:
		{
			return D3DFMT_A8R8G8B8;
		}
		/// 32-bit pixel format, 8 bits for red, green, blue and alpha.
		//case PF_R8G8B8A8:
		//	{
		//		//return D3DFMT_R8G8B8A8;
		//	}
		/// 32-bit pixel format, 8 bits for red, 8 bits for green, 8 bits for blue
		/// like PF_A8R8G8B8, but alpha will get discarded
	case PF_X8R8G8B8:
		{
			return D3DFMT_X8R8G8B8;
		}
		/// DDS (DirectDraw Surface) DXT1 format
	case PF_DXT1:
		{
			return D3DFMT_DXT1;
		}
		/// DDS (DirectDraw Surface) DXT5 format
	case PF_DXT5:
		{
			return D3DFMT_DXT5;
		}
	default:
		{
			return D3DFMT_UNKNOWN;
		}
	}
}

void CD3D9Mapping::makeD3DXMatrix( const CMatrix4& mat, D3DXMATRIX& matOut )
{
	// Transpose matrix
	// D3D9 uses row vectors i.e. V*M
	// Ogre, OpenGL and everything else uses column vectors i.e. M*V

	matOut.m[0][0] = mat.m[0][0];
	matOut.m[0][1] = mat.m[1][0];
	matOut.m[0][2] = mat.m[2][0];
	matOut.m[0][3] = mat.m[3][0];
	matOut.m[1][0] = mat.m[0][1];
	matOut.m[1][1] = mat.m[1][1];
	matOut.m[1][2] = mat.m[2][1];
	matOut.m[1][3] = mat.m[3][1];
	matOut.m[2][0] = mat.m[0][2];
	matOut.m[2][1] = mat.m[1][2];
	matOut.m[2][2] = mat.m[2][2];
	matOut.m[2][3] = mat.m[3][2];
	matOut.m[3][0] = mat.m[0][3];
	matOut.m[3][1] = mat.m[1][3];
	matOut.m[3][2] = mat.m[2][3];
	matOut.m[3][3] = mat.m[3][3];
}
//---------------------------------------------------------------------
void CD3D9Mapping::convertD3DXMatrix( const D3DXMATRIX& mat, CMatrix4& matOut )
{
	matOut.m[0][0] = mat.m[0][0];
	matOut.m[1][0] = mat.m[0][1];
	matOut.m[2][0] = mat.m[0][2];
	matOut.m[3][0] = mat.m[0][3];
	matOut.m[0][1] = mat.m[1][0];
	matOut.m[1][1] = mat.m[1][1];
	matOut.m[2][1] = mat.m[1][2];
	matOut.m[3][1] = mat.m[1][3];
	matOut.m[0][2] = mat.m[2][0];
	matOut.m[1][2] = mat.m[2][1];
	matOut.m[2][2] = mat.m[2][2];
	matOut.m[3][2] = mat.m[2][3];
	matOut.m[0][3] = mat.m[3][0];
	matOut.m[1][3] = mat.m[3][1];
	matOut.m[2][3] = mat.m[3][2];
	matOut.m[3][4] = mat.m[3][3];
}

void CD3D9Mapping::makeD3DXVector3( const CVector3& vec, D3DXVECTOR3& vecOut )
{
	vecOut.x = vec[0];
	vecOut.y = vec[1];
	vecOut.z = vec[2];
}

void CD3D9Mapping::converteD3DXVector3( const D3DXVECTOR3& vec, CVector3& vecOut )
{
	vecOut[0] = vec.x;
	vecOut[1] = vec.y;
	vecOut[2] = vec.z;
}

END_WARE